import { AxiosInstance } from "axios"
import { sleep } from "../../Utils"
import { createRequest, wrapperSend } from "./request"
import { FailResponse,Response } from "./responses"



export type CallBack = () => void
export type ErrorHandle = (status:number) => void

export class ApiBaseOptions {
  token?: string
  userID?: number
  roleId?: number
  onError?: ErrorHandle
  beforeSend?: CallBack
  afterSend?: CallBack

  setCredentials(token?: string, userID?: number,roleID?: number) {
    this.token = token
    this.userID = userID
    this.roleId = roleID
  }

  removeCredentials() {
    this.token = undefined
    this.userID = undefined
    this.roleId = undefined
  }

  setOnError(onError: ErrorHandle) {
    this.onError = onError
  }
  
  setBeforeSend(beforeSend: CallBack) {
    this.beforeSend = beforeSend
  }

  setAfterSend(afterSend: CallBack) {
    this.afterSend = afterSend
  }

}

type RequestOption = {
  back: boolean
  encrypt: boolean
}

const defaultOption: RequestOption = {
  back: false,
  encrypt: true
}

export class ApiBase {
  request: AxiosInstance
  apiOption?: ApiBaseOptions

  constructor(apiOption: ApiBaseOptions) {
    this.request = createRequest()
    this.apiOption = apiOption
  }

  protected post = async <T = any>(url = "", body: any = {},requestOption?: RequestOption) => {
    requestOption = {
      ...defaultOption,
      ...(requestOption || {})
    }

    if (requestOption.back && this.apiOption?.beforeSend) {
      this.apiOption.beforeSend()
    }
    let encrypt = body
    // 加密暂时省略

    const [res] = await Promise.all<Response<any> | FailResponse, unknown>([
      wrapperSend(
        () => this.request.post(url, encrypt, { headers: { token: this.apiOption?.token, user_id: this.apiOption?.userID ,role_id: this.apiOption?.roleId} }),
        this.apiOption?.onError
      ),
      sleep(500)
    ])

    if (requestOption.back && this.apiOption?.afterSend) {
      this.apiOption.afterSend()
    }
    
    if (res.success) {
      return res as Response<T>
    } else {
    return res as FailResponse
    }
  }


}